package com.juanjuan.myproject.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.juanjuan.myproject.config.ThreadPoolConfig;
import com.juanjuan.myproject.entity.Rule;
import com.juanjuan.myproject.mapper.RuleMapper;
import com.juanjuan.myproject.service.RuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 规则表 服务实现类
 * </p>
 *
 * @author zhaocun
 * @since 2023-10-25
 */
@Service
@Slf4j
public class RuleServiceImpl extends ServiceImpl<RuleMapper, Rule> implements RuleService {

    @Autowired
    private RuleMapper ruleMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public List<Rule> getRuleList() {
        List<Rule> rulesList = ruleMapper.getRuleList();
        return rulesList;
    }

    @Override
    public List<Rule> UpdateRule(JSONObject jsonObject) {
        long l = System.currentTimeMillis();
        String url = "https://appcs.jbysoft.com/risk/manage/queryDecisionTables";
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("zzbs", " 1604000001");
        httpHeaders.add("zzbm", " bbPro");
        httpHeaders.add("login-token", "bb4a07f29b3fbcca8739a99284f90fe224:zmd");
        httpHeaders.add("channel", " zmd");
        //HttpHeaders httpHeaders = request.getHeaders();
        HttpEntity<Object> jsonObjectHttpEntity = new HttpEntity<>(jsonObject, httpHeaders);
        ResponseEntity<Object> objectResponseEntity = restTemplate.postForEntity(url, jsonObjectHttpEntity, Object.class);
        long l2 = System.currentTimeMillis();
        log.info("请求接口的时间为： " + (l2 - l));
        Object body = objectResponseEntity.getBody();
        Map<String, JSONObject> map = (Map<String, JSONObject>) body;
        List<JSONObject> jsonObjects = (List<JSONObject>) map.get("resultList");
        log.info("总条数为：" + jsonObjects.size());
        List<Rule> ruleList = new ArrayList<>();
        for (int i = 0; i < jsonObjects.size(); i++) {
            Rule rule = new Rule();
            JSONObject resultJson = JSON.parseObject(JSON.toJSON(jsonObjects.get(i)).toString());
            String key = resultJson.getString("key");
            String ruleType = resultJson.getString("ruleType");
            String name = resultJson.getString("name");
            String dxbh = resultJson.getString("dxbh");
            StringBuilder functionKey=new StringBuilder();
            //获取nodes内容
            JSONObject nodesJson1 = JSON.parseObject(resultJson.getString("nodes"));
            //得到nodes并转为lsit
            List nodes = (List) nodesJson1.get("nodes");
            JSONObject rcJson = new JSONObject();
            for (int m = 0; m < nodes.size(); m++) {
                JSONObject nodesJson2 = JSON.parseObject(JSON.toJSON(nodes.get(m).toString()).toString());
                //一个nodes包含多个规则入参，isResult=1代表规则是结果了没有入参了
                if (nodesJson2.containsKey("nodes") && nodesJson2.getIntValue("isResult") != 1) {
                    List nodes1 = (List) nodesJson2.get("nodes");
                    for (int i1 = 0; i1 < nodes1.size(); i1++) {
                        JSONObject nodesSecond = JSON.parseObject(JSON.toJSON(nodes1.get(i1).toString()).toString());
                        //到底最后一个规则就跳出本次循环，继续下一次
                        if (nodesSecond.getIntValue("isResult") == 1) {
                            continue;
                        }
                        String variable = nodesSecond.getString("variable");
                        String replace = variable.replace("*", "");
                        String[] split = replace.split(",");
                        for (String rc : split) {
                            rcJson.put(rc, "");
                        }
                    }
                }
                String variable = nodesJson2.getString("variable");
                functionKey= functionKey.append(nodesJson2.getString("functionKey"));
                String replace = variable.replace("*", "");
                String[] split = replace.split(",");
                for (String rc : split) {
                    if (rc.contains("'")){
                        rc=rc.replace("'","");
                    }
                    rcJson.put(rc, "");
                    rcJson.put("fkRuleKey", key);

                }
                rcJson.put("jgbh", "1604000001");
            /*    String variable = nodesJson2.getString("variable");
                    String replace = variable.replace("*", "");
                    String[] split = replace.split(",");
                    for (String rc : split) {
                        rcJson.put(rc, "");
                    }*/
            }
            rule.setDxbh(dxbh);
            rule.setRuleKey(key);
            rule.setFunctionKey(functionKey.toString());
            rule.setName(name);
            rule.setNodes(rcJson.toJSONString());
            rule.setRuleType(ruleType);
            ruleList.add(rule);
        }
       ruleList = this.getSfrhnr(ruleList, httpHeaders);
        int i = ruleMapper.insertBatch(ruleList);
        log.info("返回结果：  " + i);
        long l1 = System.currentTimeMillis();
        log.info("总用时为： " + (l1 - l));
        return ruleList;
    }

    /**
     * 修改数据库的规则的入参填写
     *
     * @param jsonObject
     * @return
     */
    @Override
    public List<Rule> getRuleParms(JSONObject jsonObject) {

        jsonObject.entrySet().removeIf(etry->etry.getValue()==null);
        QueryWrapper<Rule> ruleQueryWrapper = new QueryWrapper<>();
        ruleQueryWrapper.eq("is_fill", "0");
        String dxbh="dxbh";
        String sxbh="taskNumber";
        jsonObject.put("jgbh","1604000001");
        if (jsonObject.containsKey(dxbh)){
            ruleQueryWrapper.eq(dxbh,jsonObject.getString(dxbh));
        }if (jsonObject.containsKey(sxbh)){
            String string = jsonObject.getString(sxbh);
            String taskNumber = string.substring(0,5);
            ruleQueryWrapper.eq(dxbh,taskNumber);
        }
        List<Rule> ruleList = ruleMapper.selectList(ruleQueryWrapper);
        Iterator<Rule> iterator = ruleList.iterator();
        while (iterator.hasNext()){
            Rule rule = iterator.next();
            rule.setIsFill(1);
            JSONObject jsonObject1 = JSONObject.parseObject(rule.getNodes());
            jsonObject1.entrySet().forEach(entry -> {
                 String key = entry.getKey();
                // 判断是否是纯数字
                // 正则表达式
                String str = "-?\\d+(\\.\\d+)?";
                if (key.matches(str)) {
                    log.info("key1: " + key);
                    jsonObject1.put(key, key);
                } else {
                    boolean isNumeric = key.matches(str);
                    if (isNumeric && !key.equals("fkRuleKey")) {
                        jsonObject1.put(key, key);
                    } else if (!isNumeric) {
                        boolean b = jsonObject.containsKey(key);
                        if (b && !key.equals("fkRuleKey")) {
                            String string = jsonObject.getString(key);
                            jsonObject1.put(key, string);
                        } else if (!b && !key.equals("fkRuleKey")) {
                            rule.setIsFill(0);
                        }
                    }
                }
            });

            rule.setNodes(jsonObject1.toJSONString());
        }

        log.info("rist: " + ruleList.get(0));
        int i = ruleMapper.updateBatch(ruleList);
        log.info("成功的数量为：" + i);
        return ruleList;
    }


    @Override
    public List<Rule> isBoolenIsSecuss() {
        QueryWrapper<Rule> ruleQueryWrapper = new QueryWrapper<>();
        ruleQueryWrapper.eq("is_susess", "0");
        List<Rule> list = ruleMapper.selectList(ruleQueryWrapper);
        long l = System.currentTimeMillis();
        String url = "http://10.100.51.11:30501/risk/manage/ruleCheckByKey.service";
        //调用接口过慢调用线程池调用
        ThreadPoolExecutor executor = ThreadPoolConfig.getExecutor();
        ArrayList<Future<Rule>> futures = new ArrayList<>();
        for (Rule rule : list) {
            Future<Rule> future  = executor.submit(() -> {
                JSONObject jsonObject = JSONObject.parseObject(rule.getNodes().toString());
                ResponseEntity<Object> objectResponseEntity = restTemplate.postForEntity(url, jsonObject, Object.class);
                Object body = objectResponseEntity.getBody();
                String strb = body.toString();
                System.out.println("strb==" + strb);
                //判断是否失败
                if (!strb.contains("规则脚本错误")) {
                    rule.setIsSusess(1);
                }
                return rule;
            });
            futures.add(future);
        }
        log.info("执行完成了");
        executor.shutdown();
        try {
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  /*      list.forEach(rule -> {
                    JSONObject jsonObject = JSONObject.parseObject(rule.getNodes().toString());
                    ResponseEntity<Object> objectResponseEntity = restTemplate.postForEntity(url, jsonObject, Object.class);
                    Object body = objectResponseEntity.getBody();
                    String strb = body.toString();
                    System.out.println("strb==" + strb);
                    //判断是否失败
                    if (!strb.contains("ret=1")) {
                        rule.setIsIusess(1);
                    }
                });*/
        long l1 = System.currentTimeMillis();
        log.info("总用时为：+"+(l1-l));
        int i = ruleMapper.updateBatchIsSecuss(list);
        log.info("是否修改调用成功： "+i);
        return list;
    }

private List<Rule>  getSfrhnr(List<Rule> ruleList,HttpHeaders httpHeaders){
    long l = System.currentTimeMillis();
    String url = "https://appcs.jbysoft.com/risk/manage/queryplugin.service";
    //HttpHeaders httpHeaders = request.getHeaders();
    ThreadPoolExecutor executor = ThreadPoolConfig.getExecutor();
    List<Future<Rule>>futures=new ArrayList<>();
    for (int i = 0; i < ruleList.size(); i++) {
        final int index=i;
        Future<Rule> future = executor.submit(() -> {
            log.info("执行了任务1"+index);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("jsKey", ruleList.get(index).getFunctionKey());
            HttpEntity<JSONObject> httpEntity = new HttpEntity<>(jsonObject, httpHeaders);
            ResponseEntity<Object> objectResponseEntity = restTemplate.postForEntity(url, httpEntity, Object.class);
            Object body = objectResponseEntity.getBody();
            String json = JSON.toJSONString(body);
            JSONObject jsonObject1 = JSON.parseObject(json);
            JSONObject data = jsonObject1.getJSONObject("data");
            String js = data.getString("js");
            log.info("算法内容为："+js);
            // 正则表达式用于匹配 JavaScript 注释（支持多行注释）
            String regex = "/\\*.*?\\*/|//.*";
            // 使用 Pattern.DOTALL 标志以匹配多行注释
            Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
            Matcher matcher = pattern.matcher(js);

            // 用空字符串替换匹配到的注释部分
            String result = matcher.replaceAll("");
            if (result.contains("if")){
                ruleList.get(index).setLogic(1);
            }
            ruleList.get(index).setSfnr(result);
            return ruleList.get(index);
        });
        futures.add(future);
    }
    log.info("执行完成了");
    executor.shutdown();
    try {
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return ruleList;
}

}
